import java.util.ArrayList;
import java.util.Scanner;

public class UserInterface
{
	private static Scanner _scanner;
	private static CPCGame _cpcGame;
	private static ArrayList<ScoreCategory> _unscoredCategories;
	
	public static void main(String[] args)
	{		
		ScoreCategory categoryToScore;
		_scanner = new Scanner(System.in);
		Die[] currentRoll;
		ArrayList<Integer> indexesToReRoll;
		ArrayList<Integer> indexesForScoring;
		int remainingReRolls;
		
		boolean reRoll = true;
		
		initializeGame();
		
		// While the score card is not full, keep looping.
		while(!_cpcGame.isScorecardComplete())
		{
			if(promptToRoll("roll"))
			{
				currentRoll = _cpcGame.rollAll();
				displayCurrentRoll(currentRoll);
				remainingReRolls = _cpcGame.getRemainingReRolls();				
				while(remainingReRolls > 0 && reRoll)
				{
					if(remainingReRolls > 0)
					{
						System.out.println("You have " + remainingReRolls + " remaining re-rolls.");
						reRoll = true;
					}
					
					if(promptToRoll("re-roll any of"))
					{			
						//user input array or array list
						indexesToReRoll = getIndexesForReRoll();
						
						currentRoll = _cpcGame.roll(indexesToReRoll);
						displayCurrentRoll(currentRoll);
						_cpcGame.decrementRemainingReRolls();
						
						// Calculate the cost of the re-roll into the scorecard
					}
					else
					{
						reRoll = false;
					}
					
					remainingReRolls = _cpcGame.getRemainingReRolls();
				}
				
				reRoll = true;

				indexesForScoring = getIndexesForScoring(currentRoll);
				categoryToScore = getScoringCategory();
				
				System.out.println("You scored: " + _cpcGame.score(categoryToScore, indexesForScoring));

				// Display scoring categories
				displayScoredCategories();
				
			}
			else
			{
				System.out.println("You still have unplayed categories in your score-card.");
			}
						
		}
		
		// display total scores
		displayGameResults();
	}
	
	/**
	 * Called when used to display the results of the card.
	 */
	private static void displayGameResults()
	{
		System.out.println("----------------------");
		System.out.println("Congratulations you finished the game!");
		System.out.println("----------------------");
		System.out.println("Final ScoreCard:");
		
		for(ScoreCategory category :_cpcGame.getScoredCategories())
		{
			System.out.println(category.getName() + " Score:" + category.getScore());
		}
		
		System.out.println("Re-roll bonus: +" + _cpcGame.getReRollBonus());
		System.out.println("Chance Deduction: -" + _cpcGame.getChanceDeduction());
		System.out.print("Total Score: " + _cpcGame.getTotalScore());
	}
	
	
	/**
	 * Called to display the scored categories.
	 */
	private static void displayScoredCategories()
	{
		System.out.println("Status of Scorecard:");
		for(ScoreCategory category :_cpcGame.getScoredCategories())
		{
			System.out.println(category.getName() + " Score:" + category.getScore());
		}
		
		System.out.println("Total Score: " + _cpcGame.getTotalScore());
	}
	
	/**
	 * Gets all the scoring categories
	 */
	private static ScoreCategory getScoringCategory()
	{
		_unscoredCategories = _cpcGame.getUnscoredCategories();
		int i = 0;
		int userInput = -1;
		
		while(userInput == -1)
		{
			System.out.println("Categories that haven't been used:");
			for(ScoreCategory category : _unscoredCategories)
			{
				System.out.println((i+1) + ".- " + category.getName() + ".");
				i++;
			}
			
			System.out.println("Pick a category:");
			userInput = Integer.parseInt((_scanner.nextLine()));
			
			if(userInput >  i || userInput < 0)
			{
				userInput = -1;
				i = 0;
			}
		}
		
		
		return _unscoredCategories.get(userInput-1);
	}
	
	/**
	 * Used to get input from user for scoring
	 * @return Indexes
	 */
	private static ArrayList<Integer> getIndexesForScoring(Die[] currentRoll)
	{
		ArrayList<Integer> indexesForScoring;
		
		indexesForScoring = new ArrayList<Integer>();
		boolean[] usedIndex = new boolean[8];
		
		while(indexesForScoring.size() != 5)
		{
			indexesForScoring.clear();
			
			System.out.println("Which dies do you want to use for scoring? Example: 1,3,5,7,6.");
			System.out.println("If none given, default chosen: 1,2,3,4,5. ");
			
			//Which indexes you want to roll?
			String userInput = _scanner.nextLine();
			String[] input = userInput.split(",");
			
			if(userInput.length() == 0)
			{
				indexesForScoring.add(0);
				indexesForScoring.add(1);
				indexesForScoring.add(2);
				indexesForScoring.add(3);
				indexesForScoring.add(4);
			}
			else if(input.length == 5)
			{
				for(int i = 0 ; i < usedIndex.length ; i++)
				{
					usedIndex[i] = false;
				}
				
				for(String index : input)
				{
					if(index.equals("1"))
					{
						if(!usedIndex[0])
						{
							indexesForScoring.add(0);
							usedIndex[0] = true;
						}
					}
					if(index.equals("2"))
					{
						if(!usedIndex[1])
						{
							indexesForScoring.add(1);
							usedIndex[1] = true;
						}
					}
					if(index.equals("3"))
					{
						if(!usedIndex[2])
						{
							indexesForScoring.add(2);
							usedIndex[2] = true;
						}
					}
					if(index.equals("4"))
					{
						if(!usedIndex[3])
						{
							indexesForScoring.add(3);
							usedIndex[3] = true;
						}
					}
					if(index.equals("5"))
					{
						if(!usedIndex[4])
						{
							indexesForScoring.add(4);
							usedIndex[4] = true;
						}
					}
					if(index.equals("6"))
					{
						if(!usedIndex[5])
						{
							indexesForScoring.add(5);
							usedIndex[5] = true;
						}
					}
					if(index.equals("7"))
					{
						if(!usedIndex[6])
						{
							indexesForScoring.add(6);
							usedIndex[6] = true;
						}
					}
					if(index.equals("8"))
					{
						if(!usedIndex[7])
						{
							indexesForScoring.add(7);
							usedIndex[7] = true;
						}
					}
				}
			}
			
		}
		
		System.out.println("You chose the following dice for scoring:");
		
		for(int index : indexesForScoring)
		{
			System.out.println((index+1) + ".- " + currentRoll[index].getNumber() + "/" + currentRoll[index].getColor());
		}
		
		return indexesForScoring;
	}
	
	/**
	 *  Used for get indexes for re-roll.
	 * @return Indexes
	 */
	private static ArrayList<Integer> getIndexesForReRoll()
	{
		ArrayList<Integer> indexesToReRoll;
		
		System.out.println("Which dies do you want to re-roll? Example: 1,3,4,5 . Leave blank if none.");
		
		//Which indexes you want to roll?
		String userInput = _scanner.nextLine();
		
		indexesToReRoll = new ArrayList<Integer>();
		
		String[] input = userInput.split(",");
		
		for(String index : input)
		{
			if(index.equals("1"))
			{
				indexesToReRoll.add(0);
			}
			if(index.equals("2"))
			{
				indexesToReRoll.add(1);
			}
			if(index.equals("3"))
			{
				indexesToReRoll.add(2);
			}
			if(index.equals("4"))
			{
				indexesToReRoll.add(3);
			}
			if(index.equals("5"))
			{
				indexesToReRoll.add(4);
			}
			if(index.equals("6"))
			{
				indexesToReRoll.add(5);
			}
			if(index.equals("7"))
			{
				indexesToReRoll.add(6);
			}
			if(index.equals("8"))
			{
				indexesToReRoll.add(7);
			}
		}
		
		return indexesToReRoll;
	}
	
	/**
	 * Will prompt the user if he wants to re-roll.
	 * @param action
	 * @return Want to re-roll
	 */
	private static boolean promptToRoll(String action)
	{
		boolean result = false;
		boolean validInput = false;
		
		while(!validInput)
		{
			System.out.println(_cpcGame.getPlayerName() + ", would you like to " + action + " the dice? (y/n)");
			String ifPlay = _scanner.nextLine(); 
			
			if(ifPlay.equals("y"))
			{
				result = true;
				validInput = true;
			}
			else if(ifPlay.equals("n"))
			{
				result = false;
				validInput = true;
			}
		}
		
		return result;
	}

	/**
	 * Starts game.
	 */
	private static void initializeGame()
	{
		System.out.println("Welcome to a new CPC game!");
		
		_cpcGame = new CPCGame();
		setUserInfo();
	}
	
	/**
	 * Sets user name.
	 */
	private static void setUserInfo()
	{
		String userName;
		
		System.out.print("What's your name?");
		userName = _scanner.nextLine();
		CPCGame.setPlayerName(userName);
		
		System.out.println("This is going to be a fun game, " + userName + ".");
	}
	
	/**
	 * Displays the user name.
	 * @param currentRoll
	 */
	private static void displayCurrentRoll(Die[] currentRoll)
	{
		System.out.println("Your roll is");
		for(int i = 0; i < currentRoll.length; i++)
		{
			System.out.println((i+1) + ".- " + currentRoll[i].getNumber() + "/" + currentRoll[i].getColor());
		}
	}
}